/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.meraklisina.latexeditor.mdi.TextEditor;

import java.awt.Component;
import java.io.File;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;

import com.meraklisina.latexeditor.mdi.Common.FileOperations;
import com.meraklisina.latexeditor.mdi.Common.Tools;
import com.meraklisina.latexeditor.mdi.DialogActions.ActionSave;
import com.meraklisina.latexeditor.mdi.Pane.SweTextPane;
import com.meraklisina.latexeditor.xmltools.XmlHelper;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.swing.JTabbedPane;
import javax.swing.text.Element;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyledDocument;
import javax.swing.text.View;

/**
 *
 * @author Eray
 */
public class TextEditors
{
    Tools CommonTool = new Tools();

    private static String Name_TabScrollPane = "txt_TabScrollPane";
    private static String Name_TabTextEditor = "txt_TabTextEditor";
    private static String Name_ScrapFile = "ScrapFile";

    private boolean IsTextChanged;
    private String ScrapPath, RealPath;
    private String JScrollPaneName, JTextPaneName;

    private static ArrayList<TextEditors> Editors = new ArrayList<TextEditors>();


    // <editor-fold defaultstate="collapsed" desc="Properties">

    public boolean getIsTextChanged()
    { return this.IsTextChanged; }
    public void setIsTextChanged(boolean IsTextChanged)
    { this.IsTextChanged = IsTextChanged; }

    public String getScrapPath()
    { return this.ScrapPath; }
    public void setScrapPath(String ScrapPath)
    { this.ScrapPath = ScrapPath; }

    public String getRealPath()
    { return this.RealPath; }
    public void setRealPath(String RealPath)
    { this.RealPath = RealPath; }

    public String getJScrollPaneName()
    { return this.JScrollPaneName; }
    public void setJScrollPaneName(String JScrollPaneName)
    { this.JScrollPaneName = JScrollPaneName; }

    public String getJTextPaneName()
    { return this.JTextPaneName; }
    public void setJTextPaneName(String JTextPaneName)
    { this.JTextPaneName = JTextPaneName; }

    @SuppressWarnings("static-access")
    public ArrayList<TextEditors> getEditors()
    { return this.Editors; }

    /**
     * @return the Name_TabScrollPane
     */
    public static String getName_TabScrollPane() {
        return Name_TabScrollPane;
    }

    /**
     * @param aName_TabScrollPane the Name_TabScrollPane to set
     */
    public static void setName_TabScrollPane(String aName_TabScrollPane) {
        Name_TabScrollPane = aName_TabScrollPane;
    }

    /**
     * @return the Name_TabTextEditor
     */
    public static String getName_TabTextEditor() {
        return Name_TabTextEditor;
    }

    /**
     * @param aName_TabTextEditor the Name_TabTextEditor to set
     */
    public static void setName_TabTextEditor(String aName_TabTextEditor) {
        Name_TabTextEditor = aName_TabTextEditor;
    }

    /**
     * @return the Name_ScrapFile
     */
    public static String getName_ScrapFile() {
        return Name_ScrapFile;
    }

    /**
     * @param aName_ScrapFile the Name_ScrapFile to set
     */
    public static void setName_ScrapFile(String aName_ScrapFile) {
        Name_ScrapFile = aName_ScrapFile;
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Constructors">

    public TextEditors()
    {
    }
    public TextEditors(String Name_TextEditorsXmlFile)
    {
        Tools.setXmlFileName_TextEditors(Name_TextEditorsXmlFile);
    }
    public TextEditors(boolean IsTextChanged, String ScrapPath, String RealPath)
    {
        this.IsTextChanged = IsTextChanged;
        this.ScrapPath = ScrapPath;
        this.RealPath = RealPath;
    }
    public TextEditors(boolean IsTextChanged, String ScrapPath, String RealPath, String JScrollPaneName, String JTextPaneName)
    {
        this.IsTextChanged = IsTextChanged;
        this.ScrapPath = ScrapPath;
        this.RealPath = RealPath;
        this.JScrollPaneName = JScrollPaneName;
        this.JTextPaneName = JTextPaneName;
    }
    // </editor-fold>

    /**
     * Comments the selected text of the <b>current</b> editor with the given special
     * comment character. For LaTeX the comment character should be "<b>%</b>".
     * Also, <b>IsCommentIn</b> parameter determines whether you comment in or out.
     * If this parameter given as <b>TRUE</b>, the comment character will be added.
     * Otherwise, it will delete the charater.
     *
     * @param Editors
     * @param IsCommentIn
     * @param CommentCharacter
     */
    public void CommentInOut(JTabbedPane Editors, boolean IsCommentIn, String CommentCharacter)
    {
        InsertTextAtStart(GetJTextPane(Editors),IsCommentIn,CommentCharacter);
    }
    /**
     * Clears the current TextEditors collection.
     */
    public void Clear()
    {
        Editors.clear();
    }
    /**
     * Deletes a TextEditors object from the current TextEditors collection.
     *
     * @param Index
     * @return True or False depending if the job is done or not
     */
    public boolean RemoveAt(int Index)
    {
        try {Editors.remove(Index); return true;}
        catch(Exception ex){return false;}
    }

    // <editor-fold defaultstate="collapsed" desc="Close & Save Tab Functions">

    /**
     * Closes the current tab of the JTabbedPane and removes this tab. It also deletes
     * the temporary scrap file if there is any.
     *
     * @param TabEditors
     */
    public void CloseTab(JTabbedPane TabEditors)
    {
        int Index = TabEditors.getSelectedIndex();

        if(!GetObjectAt(Index).getScrapPath().isEmpty())// Deletes if any scrap file related to the tab and this HAS to be BEFORE removing the item from the Editors array
        {
            File file = new File(Tools.getStartupPath() + GetObjectAt(Index).getScrapPath());
            file.delete();
        }

        //TabEditors.remove(GetSelectedScrollPane(Form, Index)); // Remove from the form physically
        TabEditors.remove(Index);

        RemoveAt(Index); //Remove from the Editors Array.. This HAS TO came AFTER TAB REMOVE

        if(Editors.size() <= 0)
            AddTab(TabEditors, false, "", "", null, 0);
    }
    /**
     * Closes the current tab of the JTabbedPane and removes this tab. It also deletes
     * the temporary scrap file if there is any.
     *
     * @param TabEditors
     */
    public void CloseTabAt(JTabbedPane TabEditors, int Index)
    {
        if(!GetObjectAt(Index).getScrapPath().isEmpty())// Deletes if any scrap file related to the tab and this HAS to be BEFORE removing the item from the Editors array
        {
            File file = new File(Tools.getStartupPath() + GetObjectAt(Index).getScrapPath());
            file.delete();
        }

        //TabEditors.remove(GetSelectedScrollPane(Form, Index)); // Remove from the form physically
        TabEditors.remove(Index);

        RemoveAt(Index); //Remove from the Editors Array.. This HAS TO came AFTER TAB REMOVE

        if(Editors.size() <= 0)
            AddTab(TabEditors, false, "", "", null, 0);
    }
    private void CloseTabsAt(JTabbedPane TabEditors, int Index)
    {
        if(!GetObjectAt(Index).getScrapPath().isEmpty())// Deletes if any scrap file related to the tab and this HAS to be BEFORE removing the item from the Editors array
        {
            File file = new File(Tools.getStartupPath() + GetObjectAt(Index).getScrapPath());
            file.delete();
        }

        //TabEditors.remove(GetSelectedScrollPane(Form, Index)); // Remove from the form physically
        TabEditors.remove(Index);

        RemoveAt(Index); //Remove from the Editors Array.. This HAS TO came AFTER TAB REMOVE

//        if(Editors.size() <= 0)
//            AddTab(TabEditors, false, "", "", null, 0);
    }
    /**
     * Closes the Currently Seelcted tab. This is used for general closing purposes.
     *
     * @param TabEditors
     */
    public void CloseTabDialog(JTabbedPane TabEditors)
    {
        ActionSave ClsActionSave = new ActionSave();
        int Index = TabEditors.getSelectedIndex();
        
        if(GetIsTextChanged(Index)) {
                        int DialogResult = JOptionPane.showConfirmDialog(
                                                         null,
                                                         "Do you want to save the changes on '" + TabEditors.getTitleAt(Index) + "'?",
                                                         "New Page",
                                                         JOptionPane.YES_NO_CANCEL_OPTION);

                        if(DialogResult == JOptionPane.YES_OPTION) {
                              ClsActionSave.SaveDialog(TabEditors, "Save", false);
                              CloseTabsAt(TabEditors, Index);
                        }

                        if(DialogResult == JOptionPane.NO_OPTION) {
                              CloseTabsAt(TabEditors, Index);
                        }
                 }
                 else {
                        CloseTabsAt(TabEditors, Index);
                 }

    }
    /**
     * Closes the tab given at the index.
     *
     * @param TabEditors
     * @param Index
     */
    public void CloseTabAtDialog(JTabbedPane TabEditors, int Index)
    {

        ActionSave ClsActionSave = new ActionSave();

        if(GetIsTextChanged(Index)) {
                        int DialogResult = JOptionPane.showConfirmDialog(
                                                         null,
                                                         "Do you want to save the changes on '" + TabEditors.getTitleAt(Index) + "'?",
                                                         "New Page",
                                                         JOptionPane.YES_NO_CANCEL_OPTION);

                        if(DialogResult == JOptionPane.YES_OPTION) {
                              ClsActionSave.SaveDialog(TabEditors, "Save", false);
                              CloseTabsAt(TabEditors, Index);
                        }

                        if(DialogResult == JOptionPane.NO_OPTION) {
                              CloseTabsAt(TabEditors, Index);
                        }
                 }
                 else {
                        CloseTabsAt(TabEditors, Index);
                 }

    }
    /**
     * Saves the current Tab.
     *
     * @param TabEditors
     * @param IsSaveAs
     */
    public void SaveTab(JTabbedPane TabEditors, boolean IsSaveAs)
    {
        ActionSave ClsActionSave = new ActionSave();
        
        try
        {
             if(GetRealPath(TabEditors.getSelectedIndex()).isEmpty() || IsSaveAs || !GetIsTextChanged(TabEditors.getSelectedIndex()))
             {
                 ClsActionSave.SaveDialog(TabEditors, "Save As...", IsSaveAs);
             }
             else if(!GetRealPath(TabEditors.getSelectedIndex()).isEmpty())
             {
                 ClsActionSave.Save(TabEditors, GetRealPath(TabEditors.getSelectedIndex()), false);
             }
         }
         catch(Exception ex)
         {
            JOptionPane.showMessageDialog(null,ex.getMessage(),"File error",JOptionPane.ERROR_MESSAGE);
         }

    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Add Functions">

    /**
     * Add tabs into the specified JTabbedPane component.
     *
     * @param TabEditors
     */
    public void AddTab(JTabbedPane TabEditors)
    {
        int Index = Editors.size();

        Editors.add(new TextEditors(false, "","", getName_TabScrollPane() + String.valueOf(Index), getName_TabTextEditor() + String.valueOf(Index))); //Adds into the Editors ArrayList
        GenerateTab(TabEditors, null, TabEditors.getTabCount());
    }
    /**
     * Add tabs into the specified JTabbedPane component.
     *
     * @param TabEditors
     * @param IsChanged
     * @param ScrapPath
     * @param RealPath
     * @param FileText
     */
    public void AddTab(JTabbedPane TabEditors, boolean IsChanged, String ScrapPath, String RealPath, File FileText)
    {
        int Index = TabEditors.getTabCount();

        Editors.add(new TextEditors(IsChanged, ScrapPath, RealPath, getName_TabScrollPane() + String.valueOf(Index), getName_TabTextEditor() + String.valueOf(Index))); //Adds into the Editors ArrayList
        GenerateTab(TabEditors, FileText, Index);
    }
    /**
     * Add tabs into the specified JTabbedPane component.
     *
     * @param TabEditors
     * @param IsChanged
     * @param ScrapPath
     * @param RealPath
     * @param FileText
     * @param Index
     */
    public void AddTab(JTabbedPane TabEditors, boolean IsChanged, String ScrapPath, String RealPath, File FileText, int Index)
    {
        Editors.add(new TextEditors(IsChanged, ScrapPath, RealPath, getName_TabScrollPane() + String.valueOf(Index), getName_TabTextEditor() + String.valueOf(Index))); //Adds into the Editors ArrayList
        GenerateTab(TabEditors, FileText, Index);
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Get Functions">

    /**
     * Gets the TextEditors object from the current TextEditors collection.
     *
     * @param Index
     * @return
     */
    public TextEditors GetObjectAt(int Index)
    {
        return Editors.get(Index);
    }
    /**
     * Gets <b>selected</b> text from the selected tab of the JTabbedPane component of
     * the current TextEditors collection.
     *
     * @return Selected text
     */
    public String GetText(JTabbedPane TabEditors)
    {
        int Index = TabEditors.getSelectedIndex();
        return GetJTextPaneAt(TabEditors, Index).getSelectedText();
    }
    /**
     * Gets <b>all</b> text from the selected tab of the JTabbedPane component of
     * the current TextEditors collection at a given Index.
     *
     * @param Index
     * @return
     */
    public String GetTextAt(JTabbedPane TabEditors, int Index)
    {
        return GetJTextPaneAt(TabEditors, Index).getText();
    }
    /**
     * This function is aimed to get the last changed TAB when application closes.
     *
     * @param TabEditors
     * @return
     */
    public int GetLastChangedEditor(JTabbedPane TabEditors)
    {
        int ReturnValue = 0;

        for(int i = Editors.size()-1; i >= 0; i--)
        {
            if(this.GetIsTextChanged(i))
            {
                ReturnValue = i;
                break;
            }
        }
        return ReturnValue;
    }
    /**
     * Gets if the current tab's text has changed or not.
     *
     * @param Index
     * @return True or False
     */
    public boolean GetIsTextChanged(int Index)
    {
        return Editors.get(Index).getIsTextChanged();
    }
    /**
     * Gets the relative temporary scrap file path at a specifed index of
     * the TextEditors collection.
     *
     * @param Index
     * @return String relative path
     */
    public String GetScrapPath(int Index)
    {
        if(!IsArrayNull(Index))
            return Editors.get(Index).getScrapPath();
        else
            return "";
    }
    /**
     * Gets the physical file path at a specifed index of
     * the TextEditors collection.
     *
     * @param Index
     * @return String physical path
     */
    public String GetRealPath(int Index)
    {
        if(!IsArrayNull(Index))
            return Editors.get(Index).getRealPath();
        else
            return "";
    }
    /**
     * Gets the name of the scrap file. This can be used to display
     * the name of the current file on the JTabbedPane.
     *
     * @param Index
     * @return String scrap file Title
     */
    public String GetScrapPathTitle(int Index)
    {
        if(!IsArrayNull(Index))
        {
           File f = new File(Editors.get(Index).getScrapPath());
           return f.getName();
        }
        else
            return "";
    }
    /**
     * Gets the name of the physical file. This can be used to display
     * the name of the current file on the JTabbedPane.
     *
     * @param Index
     * @return String physical file Title
     */
    public String GetRealPathTitle(int Index)
    {
        if(!IsArrayNull(Index))
        {
            File f = new File(Editors.get(Index).getRealPath());
            return f.getName();
        }
        else
            return "";
    }
    /**
     * Gets JTextPane from the TextEditors collection
     * in a given index.
     *
     * @param Index
     * @return Currently selected JTextPane
     */
    public JTextPane GetJTextPaneAt(JTabbedPane TabEditors, int Index)
    {
        Component CompText = CommonTool.GetComponent(TabEditors, (Editors.get(Index).getJTextPaneName()));

        //**SweTextPane textPane = Editors.get(Index).getSweEditor(); //(SweTextPane)CompText;
        JTextPane textPane = (JTextPane)CompText;
        return textPane;
    }
    /**
     * Gets currently selected JTextPane from the TextEditors collection
     *
     * @param TabEditors
     * @return
     */
    public JTextPane GetJTextPane(JTabbedPane TabEditors)
    {
        int Index = TabEditors.getSelectedIndex();

        Component CompText = CommonTool.GetComponent(TabEditors, Editors.get(Index).getJTextPaneName());
        JTextPane textPane = (JTextPane)CompText;

        return textPane;
    }
    /**
     * Gets selected JScrollPane from the TextEditors collection
     * by sending JTabbedPane's selected index.
     *
     * @param Index
     * @return Currently selected JScrollPane
     */
    public JScrollPane GetSelectedScrollPane(JTabbedPane TabEditors, int Index)
    {
        Component CompText = CommonTool.GetComponent(TabEditors, Editors.get(Index).getJScrollPaneName());
        JScrollPane ScrollPane= (JScrollPane)CompText;

        return ScrollPane;
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Set Functions">

    /**
     * Sets the text of the currently selected tab of the JTabbePane.
     *
     * @param TabEditors
     * @param StartIndex
     * @param EndIndex
     */
    public void SetSelectedTextPane(JTabbedPane TabEditors, int StartIndex, int EndIndex)
    {
        JTextPane textPane = GetJTextPane(TabEditors);
        textPane.setSelectionStart(StartIndex);
        textPane.setSelectionEnd(EndIndex);
    }
    /**
     * Sets the relative scrap path of the TextEditors collection at
     * a specifed index.
     *
     * @param Index
     * @param ScrapPath
     */
    public void SetScrapPath(int Index, String ScrapPath)
    {
        Editors.get(Index).setScrapPath(ScrapPath);
    }
    /**
     * Sets the physical path of the TextEditors collection at
     * a specifed index.
     *
     * @param Index
     * @param RealPath
     */
    public void SetRealPath(int Index, String RealPath)
    {
        Editors.get(Index).setRealPath(RealPath);
    }
    /**
     * Sets the Dirty Flag of the currently selected JTextPane.
     *
     * @param TabEditors
     * @param IsChanged
     */
    public void SetIsTextChange(JTabbedPane TabEditors, boolean IsChanged)
    {
        int Index = TabEditors.getSelectedIndex();

       SetIsTextChange(TabEditors, Index, IsChanged);
    }
    /**
     * Sets the Dirty Flag of the currently selected JTextPane.
     *
     * @param TabEditors
     * @param index
     * @param IsChanged
     */
    public void SetIsTextChange(JTabbedPane TabEditors, int index, boolean IsChanged)
    {
        int Index = index;

        if(IsChanged)
        {
            if(!TabEditors.getTitleAt(Index).contains("*"))
                TabEditors.setTitleAt(Index, TabEditors.getTitleAt(Index) + " *");
        }
        else
            TabEditors.setTitleAt(Index, TabEditors.getTitleAt(Index).replace(" *", ""));

        Editors.get(Index).setIsTextChanged(IsChanged);
    }
    /**
     * Sets the Dirty Flag of the currently selected JTextPane.
     *
     * @param TabEditors
     * @param IsChanged
     */
    public void SetTextChange(JTabbedPane TabEditors, boolean IsChanged)
    {
        SetTextChange(TabEditors, TabEditors.getSelectedIndex(), IsChanged);
    }
    /**
     * Sets the Dirty Flag of the currently selected JTextPane.
     *
     * @param TabEditors
     * @param index
     * @param IsChanged
     */
    public void SetTextChange(JTabbedPane TabEditors, int index, boolean IsChanged)
    {
        SetIsTextChange(TabEditors, index, IsChanged);

        if(!IsChanged) // This occurs only when the file is saved and a REALPATh assigned
        {
            TextEditors editor = GetObjectAt(index);
            editor.setScrapPath("");
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Load & Generate Functions">

    /**
     * Loads the TextEditors from the <i>TextEditors.xml</i> (This name is
     * default) and adds into the TextEditors Collection.
     *
     * <p>
     * While adding the TextEditors, it also creates the components like
     * JTextPane.
     * </p>
     *
     *
     * @param TabEditors
     */
    public void LoadEditors(JTabbedPane TabEditors)
    {
        FileOperations ClsFile = new FileOperations();

        int LoadedTabCount = 0;

        String FilePath = Tools.getXmlFilesPath() + Tools.getXmlFileName_TextEditors();

        if(ClsFile.IsFileExists(FilePath))
        {
            XmlHelper Helper = new XmlHelper("Parameter","Name");

            NodeList TextEditorNodes = Helper.GetNodeListFromXmlFile(FilePath, "Editor");

            for (int config = 0; config < TextEditorNodes.getLength(); config++)
            {
                Node TextEditorNode = TextEditorNodes.item(config);
                if (TextEditorNode.getNodeType() == Node.ELEMENT_NODE)
                {
                    NodeList TextEditorChildNodes = Helper.GetNodeListByAttributeValue(TextEditorNode);

                    for(int i = 0; i < TextEditorChildNodes.getLength(); i++)
                    {
                        Node TextEditorChildNode = TextEditorChildNodes.item(i);

                        String scrapPath = Helper.GetAttributeValueByAttributeName(TextEditorChildNode,"ScrapPath" + String.valueOf(i)).toString();
                        String realPath = Helper.GetAttributeValueByAttributeName(TextEditorChildNode,"RealPath" + String.valueOf(i)).toString();
                        boolean IsChanged = false;

                        if(!scrapPath.isEmpty())
                            IsChanged = true;

                        File TextFile = null;

                        if(!scrapPath.isEmpty())
                            TextFile = new File(Tools.getStartupPath() + scrapPath);
                        else if(!realPath.isEmpty())
                            TextFile = new File(realPath);

                        //GenerateTab(Form, TextFile, i); //Draws the toolsv
                        AddTab(TabEditors, IsChanged, scrapPath, realPath, TextFile, i);
                        LoadedTabCount++;
                    }

                    //This ensures at least 1 open tab when its first loaded.
                     if(LoadedTabCount <= 0)
                        AddTab(TabEditors, false, "", "", null, 0);

                }
            }
        }

    }
    private SweTextPane GenerateTab(final JTabbedPane TabEditors, File TextFile, int Index)
    {
        try
        {
            if(Index >= TabEditors.getTabCount()) //If there is already an Index created in the tab, try NEXT Index number in ELSE
            {


                JScrollPane ScrollPane = new JScrollPane();
//*                ScrollPane.setName(getName_TabScrollPane() + String.valueOf(Index));
// *               ScrollPane.setVisible(true);

                //JTextPane TextPane = new JTextPane();
                SweExt TextPane = new SweExt();
                ////TextPane.putPattern( Pattern.compile( "(%%.*$)" ), Color.BLUE ) ;



                TextPane.setName(getName_TabTextEditor() + String.valueOf(Index));
               TextPane.setVisible(true);

//////                // Text Changed listener
//////                KeyListener Listener = new KeyListener()
//////                     {
//////                        public void keyTyped(KeyEvent evt)
//////                        {
//////                            SetIsTextChange(TabEditors, true);
//////                        }
//////
//////                        public void keyPressed(KeyEvent e) {
//////                            //throw new UnsupportedOperationException("Not supported yet.");
//////                        }
//////
//////                        public void keyReleased(KeyEvent e) {
//////                            //throw new UnsupportedOperationException("Not supported yet.");
//////                        }
//////                     };
//////                TextPane.addKeyListener(Listener);


                String Title = GetRealPathTitle(Index);
//*                ScrollPane.setViewportView(TextPane);
//                //ScrollPane.setBorder(BorderFactory.createLineBorder(Color.decode("#E3E1E1")));
//*                ScrollPane.setBackground(Color.white);
                //ScrollPane.addMouseListener(mListener);

                //TabEditors.add(Title, new JLabel(Title));

                NumberedPanel numPanel = new NumberedPanel(TabEditors, TextPane, ScrollPane, getName_TabScrollPane() + String.valueOf(Index), getName_TabTextEditor() + String.valueOf(Index));

//////                JScrollPane ScrollPane1 = new JScrollPane();
//////                ScrollPane1.setViewportView(numPanel);
//////                TabEditors.addTab(Title, ScrollPane1);


                TabEditors.addTab("", numPanel);
                TabEditors.setTabComponentAt(Index,new ButtonTabComponent(TabEditors));

                ////////TabEditors.addTab(Title, ScrollPane);
                if(Title.isEmpty()) //Creates New File 1 or New File 2 on the tab
                {
                    int NewFileId = 1;

                    if(Editors.size() > 1)
                    {
                        ArrayList<Integer> array = new ArrayList<Integer>();
                        int arrayIndex = 0;

                        for(TextEditors editor : Editors)
                        {
                            if((editor.getScrapPath().isEmpty() && editor.getRealPath().isEmpty()) || (!editor.getScrapPath().isEmpty() && editor.getRealPath().isEmpty()))
                            {
                                array.add(Integer.valueOf(arrayIndex));
                                arrayIndex++;
                            }
                        }

                        NewFileId = CommonTool.GenerateId(array, 1);
                    }

                    //Title = "New File " + String.valueOf(Index+1);
                    Title = "New File " + String.valueOf(NewFileId);
                }

                TabEditors.setTitleAt(Index, Title);

                //if(TextFile != null && TextFile.getName().contains("scrap"))
                if(TextFile != null && TextFile.getName().contains(getName_ScrapFile()))
                    TabEditors.setTitleAt(Index, Title + " *");

                TabEditors.setSelectedIndex(Index);

                if(TextFile != null)
                {
                    if(TextFile.exists())
                    {
                        FileOperations ClsFile = new FileOperations();
                        //ClsFile.ReadFileWriteTextField(TextPane, TextFile);
                        SweTextPane sweTextPane = numPanel.getEditor();
                        sweTextPane.setText(ClsFile.ReadFileGetText(TextFile));


                    }
                    else if(!TextFile.getName().contains(Name_ScrapFile))
                    {
                        JOptionPane.showMessageDialog(null, "Cannot find file '" + TextFile.getPath() + "'");
                    }
                }

                return TextPane;
            }
            else
                GenerateTab(TabEditors, TextFile, Index++);
        }
        catch(Exception ex)
        {
            JOptionPane.showMessageDialog(null,ex.getMessage(),"Generating tab error",JOptionPane.ERROR_MESSAGE);
        }

        return null;
    }
    public int GetWrappedLines(SweTextPane component)
    {
        int lines = 0;

        View view = component.getUI().getRootView(component).getView(0);

        int paragraphs = view.getViewCount();

        for (int i = 0; i < paragraphs; i++)
        {
            lines += view.getView(i).getViewCount();
        }

        return lines;
    }
    /**
     * Checks the <b>ScrapFiles</b> folder and according the names of the files,
     * it automatically generates a unique number for the scrap file's name.
     *
     * @return int File number
     */
    public int GenerateScrapFileNumber()
    {
        ArrayList<Integer> ScrapNumbers = new ArrayList<Integer>();

        for(TextEditors editor : this.getEditors())
        {
            if(!editor.getScrapPath().isEmpty())
            {
                //String FileNumber = editor.getScrapPath().substring("/src/ScrapFiles/ScrapFile".length(), editor.getScrapPath().lastIndexOf('.'));
                String FileNumber = editor.getScrapPath().substring((Tools.getScrapFilesPath() + getName_ScrapFile()).length(), editor.getScrapPath().lastIndexOf('.'));
                ScrapNumbers.add(Integer.valueOf(FileNumber));
            }
        }

        return CommonTool.GenerateId(ScrapNumbers, 0);
    }
    // </editor-fold>

    /**
     * Replaces the selected text on the selected Tab. It gets the selected tab
     * automatically and replaces the text.
     *
     * @param TabEditors
     * @param Index
     * @param ReplaceText
     */
    public void ReplaceSelectedText(JTabbedPane TabEditors, int Index, String ReplaceText)
    {
        JTextPane TextPane = GetJTextPaneAt(TabEditors, Index);
        TextPane.replaceSelection(ReplaceText);
        SetIsTextChange(TabEditors, true);
    }
    /**
     * Writes into the XML file related to the TextEditor class.
     *
     * @return Boolean whether the operation done successfully or not
     */
    public boolean WriteIntoXmlTextEditor()
    {
        FileOperations ClsFile = new FileOperations();

        if(ClsFile.IsFileExists(CommonTool.getXmlFilesPath() + Tools.getXmlFileName_TextEditors()))
        {
            String XmlStartingLine = "<?xml version=" + Quote("1.0") + " encoding="+ Quote("UTF-8") + "?> \n";
            String XmlTextEditors = "<Editors> \n";

                XmlTextEditors += "<Editor> \n";

                int Index = 0;

                for(TextEditors editor : Editors)
                {
                    if(!CommonTool.isSaveInScrapFiles())
                    {
                        if(!editor.getRealPath().isEmpty() || !editor.getScrapPath().isEmpty()) //Does NOT save if the file is newly created AND HAS NOT BEEN TOUCHED
                            XmlTextEditors += String.format("<Parameter ScrapPath" + String.valueOf(Index) + "=%s RealPath" + String.valueOf(Index) + "=%s/> \n", Quote(editor.getScrapPath()), Quote(editor.getRealPath()));
                    }
                    else
                        XmlTextEditors += String.format("<Parameter ScrapPath" + String.valueOf(Index) + "=%s RealPath" + String.valueOf(Index) + "=%s/> \n", Quote(editor.getScrapPath()), Quote(editor.getRealPath()));


                    if(!Tools.SaveInScrapFiles)
                    {
                        if(!editor.getRealPath().isEmpty())
                            Index++;
                    }
                    else
                        Index++;
                }

                XmlTextEditors += "</Editor> \n";
            XmlTextEditors += "</Editors>";

            
            //WriteIntoFile(FormMain.StartupPath.replace("\\texwrite", "") + "/Library/TexWrite.Tools/src/XML/TextEditors.xml", XmlStartingLine + XmlTextEditors);
            ClsFile.WriteIntoFile(CommonTool.getXmlFilesPath() + Tools.getXmlFileName_TextEditors(), XmlStartingLine + XmlTextEditors);

            return true;
        }

        return false;
    }
    private String Quote(String Value)
    {
        char Quote = '"';
        return Quote + Value + Quote;
    }

    private boolean IsArrayNull(int Index)
    {
        if(Editors.size() > Index)
            return false;
        else
            return true;
    }

    private void InsertTextAtStart(JTextPane TextPane, boolean IsComment, String InsertedText)
    {
        try
        {
            ArrayList<Integer> LineNumbers = new ArrayList<Integer>();

            int SelectionStartOffset = TextPane.getSelectionStart();
            int SelectionEndOffset = TextPane.getSelectionEnd();
            int SelectionAdd = 0;

            int LineNumber = -1;
            StyledDocument stDoc = (StyledDocument)TextPane.getDocument();

            if(SelectionStartOffset == SelectionEndOffset && TextPane.getCaretPosition() > -1) //Helps to comment out the line if user not selected anything
            {
                    LineNumber = stDoc.getRootElements()[0].getElementIndex(TextPane.getCaretPosition());

                    LineNumbers.add(new Integer(LineNumber));
            }
            else
            {
                for(int i = SelectionStartOffset; i < SelectionEndOffset; i++)
                {
                    if(stDoc.getRootElements()[0].getElementIndex(i) != LineNumber)
                    {
                        LineNumber = stDoc.getRootElements()[0].getElementIndex(i);

                        LineNumbers.add(new Integer(LineNumber));
                    }
                }
            }
            for(int Offset : LineNumbers)
            {
                Element map = stDoc.getDefaultRootElement();
                //int row = map.getElementIndex(position);
                Element lineElem = map.getElement(Offset);
                //int col = Offset - lineElem.getStartOffset();
                int col = lineElem.getStartOffset();

                SimpleAttributeSet attributesIn = new SimpleAttributeSet();
                attributesIn = new SimpleAttributeSet();
//                attributesIn.addAttribute(StyleConstants.CharacterConstants.Foreground, Color.LIGHT_GRAY);
//                attributesIn.addAttribute(StyleConstants.CharacterConstants.Italic, Boolean.TRUE);

                SimpleAttributeSet attributesOut = new SimpleAttributeSet();
                attributesOut = new SimpleAttributeSet();
//                attributesOut.addAttribute(StyleConstants.CharacterConstants.Foreground, Color.BLACK);
//                attributesOut.addAttribute(StyleConstants.CharacterConstants.Italic, Boolean.FALSE);

                TextPane.select(lineElem.getStartOffset(), lineElem.getEndOffset()); //Selects the whole line
                String SelectedText = TextPane.getSelectedText();                    //Gets the selected string
                TextPane.replaceSelection("");                                       //Deletes the selected string from the pane

                if(IsComment)
                {
                    stDoc.insertString(col, InsertedText + SelectedText, attributesIn);
                    SelectionAdd+=InsertedText.length();
                }
                else
                {
                    stDoc.insertString(col,SelectedText.replaceFirst(InsertedText, ""), attributesOut);
                    SelectionAdd-=InsertedText.length();
                }
            }

            if(SelectionStartOffset != SelectionEndOffset)
                TextPane.select(SelectionStartOffset, SelectionEndOffset+SelectionAdd);

            //ClsTextEditor.SetIsTextChange(Form.tab_Editors, true);
        }
        catch(Exception ee)
        {
            ee.printStackTrace();
        }

    }

}
